﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace CS633_Final_Project
{
    /// <summary>
    /// Represents a triangle.
    /// </summary>
    class Triangle
    {
        public enum Status { CLEAR, CONTAMINATED, RECONTAMINATED };
        private int id;
        private PointF[] vertices;
        private PointF center;
        private Line[] edges;
        private Double area;
        private Status current_status;

        /// <summary>
        /// Constructs a triangle with the 3 given points.
        /// </summary>
        /// <param name="x">First point</param>
        /// <param name="y">Second Point</param>
        /// <param name="z">Third Point</param>
        public Triangle(PointF x, PointF y, PointF z)
        {
            id = 0;
            vertices = new PointF[3];
            edges = new Line[3];

            vertices[0] = x;
            vertices[1] = y;
            vertices[2] = z;

            edges[0] = new Line(x, y);
            edges[1] = new Line(x, z);
            edges[2] = new Line(y, z);

            CalcArea();
            CalcCenter();
            current_status = Status.CONTAMINATED;
        }

        /// <summary>
        /// Returns whether or not the two triangles are equal.
        /// </summary>
        /// <param name="obj">Another triangle.</param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            Triangle anotherTriangle = (Triangle)obj;
            return this.id.Equals(anotherTriangle.id);
        }

        /// <summary>
        /// Returns the hashcode of the triangle.
        /// </summary>
        /// <returns>Hashcode of the triangle</returns>
        public override int GetHashCode()
        {
            return this.center.GetHashCode();
        }

        /// <summary>
        /// Human readable representation of a triangle.
        /// </summary>
        /// <returns>Human readable representation of a triangle.</returns>
        public override string ToString()
        {
            return "Triangle " + id + ": " + vertices[0].ToString() + "," + vertices[1].ToString() + "," + vertices[2].ToString();
        }

        /// <summary>
        /// Id of the triangle.
        /// </summary>
        public int Id
        {
            get { return this.id; }
            set { this.id = value; }
        }

        /// <summary>
        /// Vertices of the triangle
        /// </summary>
        public PointF[] Vertices
        {
            get { return this.vertices; }
            set { this.vertices = value; }
        }

        /// <summary>
        /// Center of the triangle
        /// </summary>
        public PointF Center
        {
            get { return this.center; }
            set { this.center = value; }
        }

        /// <summary>
        /// Returns the edges of the triangle.
        /// </summary>
        public Line[] Edges
        {
            get { return this.edges; }
            set { this.edges = value; }
        }

        /// <summary>
        /// Gets the area of the triangle.
        /// </summary>
        public double Area
        {
            get { return this.area; }
            set { this.area = value; }
        }

        /// <summary>
        /// Current status of the triangle.
        /// </summary>
        public Status Current_Status
        {
            get { return this.current_status; }
            set { this.current_status = value; }
        }

        private void CalcArea()
        {
            // get A, B, C
            List<double> edge_lengths = new List<double>();
            foreach (Line edge in edges)
            {
                double length = edge.Length;
                edge_lengths.Add(length);
            }
            edge_lengths.Sort();

            // use herons formula (numerically stabilized) to calculate the area
            // http://en.wikipedia.org/wiki/Heron%27s_formula
            double a = edge_lengths.ToArray()[0];
            double b = edge_lengths.ToArray()[1];
            double c = edge_lengths.ToArray()[2];

            area = .25 * Math.Sqrt((a + (b + c)) * (c - (a - b)) * (c + (a - b)) * (a + (b - c)));
        }

        private void CalcCenter()
        {
            center = new PointF(0, 0);
            foreach (PointF vertex in vertices)
            {
                center.X += vertex.X;
                center.Y += vertex.Y;
            }
            center.X = center.X / vertices.Length;
            center.Y = center.Y / vertices.Length;
        }
    }
}
